package model.decoder;

import model.location.ReferencePoint;
import model.location.ReferencePointFactory;
import android.util.Log;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.multi.MultipleBarcodeReader;

public abstract class ZXingDecoder extends Decoder<Result>
{
	private static final String TAG = ZXingDecoder.class.getSimpleName();
	
	protected MultipleBarcodeReader _multiReader;
	
	@Override
	protected Result[] doInBackground(byte[]... bytes) 
	{
		super.doInBackground(bytes);
		return checkBinaryBitmapForCodes(bytes);
	}
	
	private Result[] checkBinaryBitmapForCodes(byte[]... bytes)
	{
		Result[] results = null;
		
		final PlanarYUVLuminanceSource source = buildLuminanceSource(bytes[0]);
		
		if(source != null)
		{
			//Zxing library requires the use of a BinaryBitmap for decoding
			BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
			try 
			{
				results = _multiReader.decodeMultiple(bitmap);
				if(results.length == 0)
					return null;
			} catch (ReaderException e) 
			{
//				Log.d(TAG, String.format("No code found %s", e.toString()));
				return null;
			}
			finally {
				bitmap = null;
			}
		}
		
		return results;
	}

	private synchronized PlanarYUVLuminanceSource buildLuminanceSource(byte[] bytes)
	{
		return new PlanarYUVLuminanceSource(bytes, _previewSize.width, _previewSize.height, 0, 0, _previewSize.width, _previewSize.height, false);
	}
	
	@Override
	protected String getDecodedData(Result result) 
	{
		return result.toString();
	}

	@Override
	protected ReferencePoint createReferencePoint(Result result) 
	{
		return ReferencePointFactory.createReferencePoint(result);
	}

}
